package com.joolun.mall.handle;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.joolun.common.core.domain.AjaxResult;
import com.joolun.mall.dto.JDCancelOrderResultDTO;
import com.joolun.mall.dto.JDFreightResultDTO;
import com.joolun.mall.entity.UserAddress;
import com.joolun.mall.enums.LogisticsChannelCodeEnum;
import com.joolun.mall.util.AddressUtil;
import com.lop.open.api.sdk.DefaultDomainApiClient;
import com.lop.open.api.sdk.domain.express.OrbLsCancelWaybillInterceptService.CancelWaybillInterceptReq;
import com.lop.open.api.sdk.domain.express.PromiseInfoApi.QueryFreightsAndPredictTimeDTO;
import com.lop.open.api.sdk.domain.express.PromiseInfoApi.WaybillFreightsAndPredictTimeDTO;
import com.lop.open.api.sdk.domain.express.WaybillJosService.WaybillDTO;
import com.lop.open.api.sdk.domain.express.WaybillJosService.WaybillResultInfoDTO;
import com.lop.open.api.sdk.plugin.LopPlugin;
import com.lop.open.api.sdk.plugin.factory.OAuth2PluginFactory;
import com.lop.open.api.sdk.request.DomainAbstractRequest;
import com.lop.open.api.sdk.request.express.OrbLsCancelWaybillInterceptServiceCancelOrderLopRequest;
import com.lop.open.api.sdk.request.express.QueryEstimatedfreightsLopRequest;
import com.lop.open.api.sdk.request.express.WaybillJosServiceReceiveOrderInfoLopRequest;
import com.lop.open.api.sdk.response.express.OrbLsCancelWaybillInterceptServiceCancelOrderLopResponse;
import com.lop.open.api.sdk.response.express.QueryEstimatedfreightsLopResponse;
import com.lop.open.api.sdk.response.express.WaybillJosServiceReceiveOrderInfoLopResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.EnumUtils;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author quyang
 * @description
 * @date 2022/1/2
 */
@DependsOn({"logisticsConfiguration"})
@Component
@Slf4j
public class JDLogisticsHandler extends LogisticsAbstractHandler {

    @Resource(name = "lopPlugin")
    private LopPlugin lopPlugin;

    @Resource(name = "defaultDomainApiClient")
    private DefaultDomainApiClient client;

    @Override
    public List<JDFreightResultDTO> freight(UserAddress senderAddress, UserAddress receiverAddress, Integer weight) {
        QueryEstimatedfreightsLopRequest request = new QueryEstimatedfreightsLopRequest();
        QueryFreightsAndPredictTimeDTO dto = new QueryFreightsAndPredictTimeDTO();
        dto.setSenderAddress(AddressUtil.getFullAddressString(senderAddress));
        dto.setReceiverAddress(AddressUtil.getFullAddressString(receiverAddress));
        dto.setWeight(weight.toString());
        dto.setBusinessType(0);
        request.setQueryFreightsAndPredictTimeDTO(dto);
        QueryEstimatedfreightsLopResponse response = execute(request);
        log.info(JSON.toJSONString(response));
        Assert.notNull(response, "获取运费失败");
        Assert.isTrue(response.getFreightsAndPredictTimeResponseDTO().getStatusCode().equals(0), "未获取到运费结果");
        List<WaybillFreightsAndPredictTimeDTO> data = response.getFreightsAndPredictTimeResponseDTO().getData();
        return data.stream().map(m -> new JDFreightResultDTO(
                m.getProductCode(),
                EnumUtils.getEnum(LogisticsChannelCodeEnum.class, m.getProductCode()).getChannel(),
                new BigDecimal(m.getFreight()),
                m.getWeight(),
                Objects.nonNull(m.getPredictTime()) ? DateUtil.formatTime(m.getPredictTime()) : ""
        )).collect(Collectors.toList());
    }

    @Override
    public AjaxResult delivery(UserAddress senderAddress, UserAddress receiverAddress, Integer weight, String orderId, String channelCode) {
        WaybillJosServiceReceiveOrderInfoLopRequest request = new WaybillJosServiceReceiveOrderInfoLopRequest();
        WaybillDTO waybillDTO = new WaybillDTO();
        waybillDTO.setSalePlat("0030001");
        waybillDTO.setCustomerCode("021K1502114");
        waybillDTO.setOrderId("deliveryNo");
        waybillDTO.setSenderName("李礼彬");
        waybillDTO.setSenderAddress("深圳市福田区福华1路98号");
        waybillDTO.setSenderMobile("18607716774");
        waybillDTO.setReceiveName("张三");
        waybillDTO.setReceiveAddress("深圳市湖北大厦楚天大酒店11楼");
        waybillDTO.setReceiveMobile("18607716774");
        waybillDTO.setPackageCount(1);
        waybillDTO.setWeight(1D);
        waybillDTO.setVloumn(0D);
        waybillDTO.setPromiseTimeType(1);

        request.setWaybillDTO(waybillDTO);
        WaybillJosServiceReceiveOrderInfoLopResponse response = execute(request);
        log.info(JSON.toJSONString(response));
        Assert.notNull(response, "京东运单下单失败");
        Assert.isTrue(response.getResult().getResultCode().equals(100), "京东运单下单结果失败");
        WaybillResultInfoDTO result = response.getResult();
        log.info("京东运单号", result.getDeliveryId());
        log.info("订单号", result.getOrderId());

        return AjaxResult.success();
    }

    @Override
    public JDCancelOrderResultDTO cancelOrder(String deliveryNo) {
        OrbLsCancelWaybillInterceptServiceCancelOrderLopRequest request = new OrbLsCancelWaybillInterceptServiceCancelOrderLopRequest();
        CancelWaybillInterceptReq dto = new CancelWaybillInterceptReq();
        dto.setCancelTime(new Date());
        dto.setVendorCode("JD00000001");
        dto.setDeliveryId(deliveryNo);
        dto.setInterceptReason("用户取消下单");
        dto.setCancelReasonCode(1);
        dto.setCancelOperator("zhangsan");
        request.setCancelRequest(dto);
        OrbLsCancelWaybillInterceptServiceCancelOrderLopResponse response = execute(request);
        Assert.notNull(response, "取消订单错误");
        if (response.getResult().getStateCode() == 1) {
            return JDCancelOrderResultDTO.success();
        }
        return JDCancelOrderResultDTO.fail();
    }

    @SneakyThrows
    private <T> T execute(DomainAbstractRequest request) {
        String serviceUrl = "https://api.jdl.cn";
        if (Objects.isNull(lopPlugin)) {
            lopPlugin = OAuth2PluginFactory.produceLopPlugin(
                    serviceUrl,
                    "cac871cc6aad468e8cc293087ba1eddf",
                    "8957a4e3287245d09b257fe415e497ae",
                    "04de4581dbae40d6a0531c246f577682"
            );
        }
        if (Objects.isNull(client)) {
            client = new DefaultDomainApiClient(serviceUrl);
        }
        request.addLopPlugin(lopPlugin);
        return (T) client.execute(request);
    }
}
